package com.ruicar.afs.cloud.afscase.loanactivatepool.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.afscase.channel.entity.*;
import com.ruicar.afs.cloud.afscase.channel.feign.ChannelFeignService;
import com.ruicar.afs.cloud.afscase.channel.service.*;
import com.ruicar.afs.cloud.afscase.channel.utils.CaseConfig;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseBaseInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseCarInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseChannelInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseContractInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseBaseInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseCarInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseChannelInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseContractInfoService;
import com.ruicar.afs.cloud.afscase.loanactivatepool.service.IContractActiveProcess;
import com.ruicar.afs.cloud.afscase.loanapprove.entity.CarInvoiceInfo;
import com.ruicar.afs.cloud.afscase.loanapprove.service.CarInvoiceInfoService;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinCostDetails;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyCostDetailsService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Description:
 * @Author: fangchenliang
 * @Date: 2020/8/19 18:04
 */
@AllArgsConstructor
@Service
@Data
@Slf4j
public class ContractActiveProcess implements IContractActiveProcess {
    private final int newCarDate=59;
    private final int oldCarDate=29;
    private CaseContractInfoService caseContractInfoService;
    private CaseBaseInfoService caseBaseInfoService;
    private ApplyCostDetailsService applyCostDetailsService;
    private CaseChannelInfoService caseChannelInfoService;
    private ChannelBaseInfoService channelBaseInfoService;
    private ChannelQuotaInfoService channelQuotaInfoService;
    private CaseConfig caseConfig;
    private ChannelFeignService channelFeignService;
    private BlacklistService blacklistService;
    private DrawerPartyService drawerPartyService;
    private ChannelWitnessInfoService channelWitnessInfoService;
    private ChannelCoopeCardealerService channelCoopeCardealerService;
    private ChannelAffiliatedUnitsService channelAffiliatedUnitsService;
    private ChannelCoopeDrawerPartyService channelCoopeDrawerPartyService;
    private ChannelAffiliatedUnitsRelService channelAffiliatedUnitsRelService;
    private CaseCarInfoService caseCarInfoService;
    private CarInvoiceInfoService carInvoiceInfoService;
    private CommonCarDealerService commonCarDealerService;
    @Transactional
    public Boolean quotaOccupy(String contractNo) {
        try {
            CaseContractInfo caseContractInfo = caseContractInfoService.getOne(Wrappers.<CaseContractInfo>query().lambda()
                    .eq(CaseContractInfo::getContractNo, contractNo)
            );
            if (caseContractInfo != null) {
                if (QuotaStatusEnum.occupation.equals(caseContractInfo.getQuotaStatus())) {
                    log.info("该合同额度已占用,跳过额度判断", contractNo);
                    return true;
                }
            }
            if (!caseContractInfo.getLendingMode().equals(AfsEnumUtil.key(LoanModelEnum.afterMortgage))) {
                CaseBaseInfo caseBaseInfo = caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>query().lambda().eq(CaseBaseInfo::getApplyNo, caseContractInfo.getApplyNo()));
                List<FinCostDetails> costDetailsList = applyCostDetailsService.list(Wrappers.<FinCostDetails>query().lambda().eq(FinCostDetails::getApplyNo, caseContractInfo.getApplyNo()));
                Assert.isTrue(!ObjectUtils.isEmpty(costDetailsList), contractNo + "未找到相应费用信息");
                BigDecimal amounts = costDetailsList.stream().map(cost -> cost.getLoanAmt())
                        .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
                CaseChannelInfo caseChannelInfo = caseChannelInfoService.getOne(Wrappers.<CaseChannelInfo>query().lambda().eq(CaseChannelInfo::getApplyNo, caseContractInfo.getApplyNo()));
                ChannelBaseInfo channelBaseInfo = channelBaseInfoService.getOne(Wrappers.<ChannelBaseInfo>query().lambda().eq(ChannelBaseInfo::getChannelCode, caseChannelInfo.getDealerNo()));
                String quotaType = transLoanMode(caseContractInfo.getLendingMode());
                Assert.isTrue(!ObjectUtils.isEmpty(quotaType), channelBaseInfo.getChannelFullName() + "未找到相应额度类型");
                ChannelQuotaInfo channelQuotaInfo = channelQuotaInfoService.getOne(Wrappers.<ChannelQuotaInfo>query().lambda()
                        .eq(ChannelQuotaInfo::getChannelId, channelBaseInfo.getId())
                        .eq(ChannelQuotaInfo::getBusinessType, caseBaseInfo.getBusinessType())
                        .eq(ChannelQuotaInfo::getQuotaType, quotaType));
                /**剩余额度*/
                BigDecimal surplusQuota = channelQuotaInfo.getSurplusQuota();
                if (channelQuotaInfo.getQuotaControlSwitch().equals(AfsEnumUtil.key(WhetherEnum.YES))) {
                    Assert.isTrue(surplusQuota.compareTo(amounts) != -1, channelBaseInfo.getChannelFullName() + "经销商额度不足");
                }
                /**占有额度*/
                BigDecimal OccupiedQuot = channelQuotaInfo.getOccupiedQuota();
                channelQuotaInfo.setOccupiedQuota(OccupiedQuot.add(amounts).setScale(2, BigDecimal.ROUND_HALF_UP));
                channelQuotaInfo.setSurplusQuota(surplusQuota.subtract(amounts).setScale(2, BigDecimal.ROUND_HALF_UP));
                channelQuotaInfoService.updateById(channelQuotaInfo);
                //同步渠道服务,更新额度信息
                List<ChannelQuotaInfo> totalChannelQuotaInfoList = new ArrayList<>();
                totalChannelQuotaInfoList.add(channelQuotaInfo);
                Map<String, String> headers = new HashMap<>();
                headers.put("clientId", caseConfig.getChannelClientId());
                headers.put("clientSecret", caseConfig.getChannelClientSecret());
                channelFeignService.updateChannelQuota(totalChannelQuotaInfoList, headers);
                //合同表额度状态字段改成占用
                caseContractInfo.setQuotaStatus(QuotaStatusEnum.occupation);
                caseContractInfoService.updateById(caseContractInfo);
                return true;
            } else {
                log.info("合同{}=>额度为先抵押后放款，跳过计算", contractNo);
                return true;
            }
        }catch (Exception e){
            log.info("合同{}=>额度判断失败", contractNo,e);
            return false;
        }
    }

    public String transLoanMode(String lendingMode) {
        if (!ObjectUtils.isEmpty(lendingMode)) {
            if (lendingMode.equals(AfsEnumUtil.key(LoanModelEnum.sign))) {
                /**渠道额度表的额度类型：1，表示签约放款；2，表示抵押签放款*/
                return QuotaTypeEnum.sign.getCode();
            } else if (lendingMode.equals(AfsEnumUtil.key(LoanModelEnum.beforeMortgage))) {
                return QuotaTypeEnum.beforeMortgage.getCode();
            } else {
                return "";
            }
        } else {
            return "";
        }
    }

    /**
     * 超期判断
     */

    public Boolean getOverdueStatus(String contractNo){
        Boolean overdueStatus=false;
        CaseContractInfo caseContractInfo = caseContractInfoService.getOne(Wrappers.<CaseContractInfo>query().lambda().eq(CaseContractInfo::getContractNo, contractNo));
        if((!ObjectUtils.isEmpty(caseContractInfo.getIsOverdue()))&&caseContractInfo.getIsOverdue().equals(WhetherEnum.YES.getCode())) {
            overdueStatus = true;
        }
        return overdueStatus;
    }
    /**
     * 黑名单命中
     */
    public Boolean getBlackListHit(String contractNo){
        AtomicReference<Boolean> blackListHit = new AtomicReference<>(false);
        CaseContractInfo caseContractInfo = caseContractInfoService.getOne(Wrappers.<CaseContractInfo>query().lambda().eq(CaseContractInfo::getContractNo, contractNo));
        if(!ObjectUtils.isEmpty(caseContractInfo)){
            //01见证人黑名单验证
            List<ChannelWitnessInfo> channelWitnessInfoList = channelWitnessInfoService.list(Wrappers.<ChannelWitnessInfo>query().lambda()
                    .eq(ChannelWitnessInfo::getWitnessIdCard,caseContractInfo.getWitnessId()));
            if(CollectionUtils.isEmpty(channelWitnessInfoList)){
                channelWitnessInfoList.forEach(channelWitnessInfo -> {
                    List<Blacklist> witnessBlacklist = blacklistService.list(Wrappers.<Blacklist>query().lambda()
                            .eq(Blacklist::getIdCode,channelWitnessInfo.getWitnessIdCard()));
                    if(CollectionUtils.isNotEmpty(witnessBlacklist)){
                        blackListHit.set(true);
                    }
                });
            }
            CaseChannelInfo caseChannelInfo = caseChannelInfoService.getOne(Wrappers.<CaseChannelInfo>query().lambda()
                    .eq(CaseChannelInfo::getApplyNo,caseContractInfo.getApplyNo()));
            //02车商黑名单验证
            if(!ObjectUtils.isEmpty(caseChannelInfo) && StringUtils.isNotBlank(caseChannelInfo.getCarDealersId())){
                CommonCarDealer commonCarDealer = commonCarDealerService.getOne(Wrappers.<CommonCarDealer>query().lambda()
                        .eq(CommonCarDealer::getId,caseChannelInfo.getCarDealersId()));
                if(!ObjectUtils.isEmpty(commonCarDealer)){
                    List<Blacklist> blacklists = blacklistService.list(Wrappers.<Blacklist>query().lambda()
                            .eq(Blacklist::getIdCode,commonCarDealer.getSocUniCrtCode()));
                    if(CollectionUtils.isNotEmpty(blacklists)){
                        blackListHit.set(true);
                    }
                }
            }
            if(!ObjectUtils.isEmpty(caseChannelInfo)){
                //03合作商黑名单验证
                ChannelBaseInfo channelBaseInfo = channelBaseInfoService.getOne(Wrappers.<ChannelBaseInfo>query().lambda()
                        .eq(ChannelBaseInfo::getChannelCode,caseChannelInfo.getDealerNo()));
                if(!ObjectUtils.isEmpty(channelBaseInfo)){
                    List<Blacklist> blacklists = blacklistService.list(Wrappers.<Blacklist>query().lambda()
                            .eq(Blacklist::getIdCode,channelBaseInfo.getSocUniCrtCode()));
                    if(CollectionUtils.isNotEmpty(blacklists)){
                        blackListHit.set(true);
                    }
                }
            }
        }
        CaseCarInfo caseCarInfo = caseCarInfoService.getOne(Wrappers.<CaseCarInfo>query().lambda()
                .eq(CaseCarInfo::getApplyNo,caseContractInfo.getApplyNo()));
        if(!ObjectUtils.isEmpty(caseCarInfo) && StringUtils.isNotBlank(caseCarInfo.getAffiliatedType())){
            //04挂靠单位黑名单验证
            if(caseCarInfo.getAffiliatedType().equals(AffiliatedWayEnum.COMPANY_AFFILIATED.getCode())
                    ||caseCarInfo.getAffiliatedType().equals(AffiliatedWayEnum.NETWORK_CAR_AFFILIATED.getCode())){
                if(StringUtils.isNotBlank(caseCarInfo.getAffCompanyId())){
                    ChannelAffiliatedUnits channelAffiliatedUnits = channelAffiliatedUnitsService.getById(caseCarInfo.getAffCompanyId());
                    List<Blacklist> blacklists = blacklistService.list(Wrappers.<Blacklist>query().lambda()
                            .eq(Blacklist::getIdCode,channelAffiliatedUnits.getSocUniCrtCode()));
                    if(CollectionUtils.isNotEmpty(blacklists)){
                        blackListHit.set(true);
                    }
                }
            }
            if(caseCarInfo.getAffiliatedType().equals(AffiliatedWayEnum.PERSONAL_AFFILIATED.getCode())){
                if(StringUtils.isNotBlank(caseCarInfo.getIndBusinessUsci())){
                    List<Blacklist> blacklists = blacklistService.list(Wrappers.<Blacklist>query().lambda()
                            .eq(Blacklist::getIdCode,caseCarInfo.getIndBusinessUsci()));
                    if(CollectionUtils.isNotEmpty(blacklists)){
                        blackListHit.set(true);
                    }
                }
            }
        }
        //05开票方黑名单验证
        CarInvoiceInfo carInvoiceInfo = carInvoiceInfoService.getOne(Wrappers.<CarInvoiceInfo>query().lambda()
                .eq(CarInvoiceInfo::getContractNo,caseContractInfo.getContractNo()));
        if(!ObjectUtils.isEmpty(carInvoiceInfo)){
            List<Blacklist> blacklists = blacklistService.list(Wrappers.<Blacklist>query().lambda()
                    .eq(Blacklist::getIdCode,carInvoiceInfo.getTaxNumber()));
            if(CollectionUtils.isNotEmpty(blacklists)){
                blackListHit.set(true);
            }
        }
        return blackListHit.get();
    }

    /**
     * 审批时效
     */
    public Boolean getPassLastTime(String contractNo){
        Boolean overdueStatus=false;
        CaseContractInfo caseContractInfo = caseContractInfoService.getOne(Wrappers.<CaseContractInfo>query().lambda()
                .eq(CaseContractInfo::getContractNo,contractNo));
        if(!ObjectUtils.isEmpty(caseContractInfo)){
            CaseBaseInfo caseBaseInfo = caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>query().lambda()
                    .eq(CaseBaseInfo::getApplyNo, caseContractInfo.getApplyNo()));
            Date lastDate = caseBaseInfo.getPassLastDate();
            if(caseBaseInfo.getPassLastDate()!=null){
                if(caseBaseInfo.getBusinessType().equals(BusinessTypeEnum.NEW_CAR.getCode())){
                    if(((new Date().getTime()-lastDate.getTime()+1000000)/(60*60*24*1000))>newCarDate){
                        overdueStatus=true;
                    }
                }else if(caseBaseInfo.getBusinessType().equals(BusinessTypeEnum.OLD_CAR.getCode())){
                    if(((new Date().getTime()-lastDate.getTime()+1000000)/(60*60*24*1000))>oldCarDate) {
                        overdueStatus = true;
                    }
                }
            }
        }
        return overdueStatus;
    }
}
